package com.tlzh.controller;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tlzh.pojo.dto.ChatRequest;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.time.LocalDateTime;

@RestController
@RequestMapping("/flux")
@CrossOrigin
public class FluxController {

    @Resource
    private  WebClient webClient;

    private final ObjectMapper objectMapper = new ObjectMapper();
    private static final Logger logger = LoggerFactory.getLogger(FluxController.class);

    /**
    *  请求不会 超时报错
    * */
    @PostMapping(value = "/ai/ollamaStreamV1", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> queryModelV1(@RequestBody ChatRequest request) {

        try {
            String requestBody = objectMapper.writeValueAsString(request);
            logger.info("Sending request body: {}", requestBody);
        } catch (Exception e) {
            logger.error("Error converting request to JSON", e);
        }

        return webClient.post()
                .uri("/api/chat")
                .contentType(MediaType.APPLICATION_JSON)
                .header("Accept-Charset", "UTF-8")
                .bodyValue(request)
                .retrieve()
                .bodyToFlux(String.class)
                .map(response -> ServerSentEvent.<String>builder().data(response).build());
    }

    @PostMapping(value = "/ai/ollamaChatStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter chatModel(@RequestBody ChatRequest request) {
        SseEmitter emitter = new SseEmitter();

        // 实际的 API 地址，你需要根据实际情况修改
        String apiUrl = "http://192.168.0.188:11434/api/chat";

        // logger 获取 请求时间
        logger.info("Request received at: {}", LocalDateTime.now());
        // 使用 WebClient 发送异步 POST 请求并获取 Flux<String>
        Flux<String> responseFlux = webClient.post()
                .uri(apiUrl)
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(request)
                .retrieve()
                .bodyToFlux(String.class);
        logger.info("Request Endt: {}", LocalDateTime.now());


        logger.info("Mono<Void> mono: {}", LocalDateTime.now());
        // 订阅 Flux 并将数据发送到 SseEmitter
        Mono<Void> mono = responseFlux
                .doOnNext(part -> {
                    try {
                        logger.info("part: {}", part);

                        ObjectMapper objectMapper = new ObjectMapper();
                        JsonNode jsonNode = objectMapper.readTree(part);

                        // 提取 context 数据
                        JsonNode contextNode = jsonNode.get("message").get("content");
                        String context = contextNode.asText();
                        logger.info("context: {}", context);

                        SseEmitter.SseEventBuilder event = SseEmitter.event()
                                .data(part)
                                .id(String.valueOf(System.currentTimeMillis()));
                        logger.info("event Start: {}", LocalDateTime.now());
                        emitter.send(event);
                        logger.info("event End: {}", LocalDateTime.now());
                    } catch (IOException  e) {
                        emitter.completeWithError(e);
                    }
                })
                .doOnComplete(emitter::complete)
                .doOnError(emitter::completeWithError)
                .then();

        // 启动异步处理
        mono.subscribe();

        return emitter;
    }


    /**
    *  @RequestBody ChatRequest request
    *  @produces = MediaType.TEXT_EVENT_STREAM_VALUE
    *  @ 有错误 ，结果强转json  public SseEmitter chatModel(@RequestBody ChatRequest request) 该方法返回的格式是json
    * */
    @PostMapping(value = "/ai/ollamaChatStreamJson", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter chatModelJson(@RequestBody ChatRequest request) {
        SseEmitter emitter = new SseEmitter();

        // 实际的 API 地址，你需要根据实际情况修改
        String apiUrl = "http://192.168.0.188:11434/api/chat";

        // 使用 WebClient 发送异步 POST 请求并获取 Flux<ApiResponse>
        Flux<ApiResponse> responseFlux = webClient.post()
                .uri(apiUrl)
                .contentType(MediaType.APPLICATION_JSON)
                .bodyValue(request)
                .retrieve()
                .bodyToFlux(ApiResponse.class);

        // 订阅 Flux 并将数据发送到 SseEmitter
        Mono<Void> mono = responseFlux
                .doOnNext(apiResponse -> {
                    try {
                        SseEmitter.SseEventBuilder event = SseEmitter.event()
                                .data(apiResponse) // 这里直接传入对象，Spring 会自动序列化为 JSON
                                .id(String.valueOf(System.currentTimeMillis()))
                                .reconnectTime(5000);
                        emitter.send(event);
                        Thread.sleep(100); // 模拟延迟
                    } catch (IOException | InterruptedException e) {
                        emitter.completeWithError(e);
                    }
                })
                .doOnComplete(emitter::complete)
                .doOnError(emitter::completeWithError)
                .then();

        // 启动异步处理
        mono.subscribe();

        return emitter;
    }


}
